﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

#if SILVERLIGHT

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace Xceed.Silverlight.ListBox
{
  partial class PanelBase
  {
    #region Static Fields

    private static readonly string HorizontalScrollBarPartName = "HorizontalScrollBar";
    private static readonly string HorizontalThumbPartName = "HorizontalThumb";

    private static readonly string VerticalScrollBarPartName = "VerticalScrollBar";
    private static readonly string VerticalThumbPartName = "VerticalThumb";

    #endregion

    private void SetScrollInfoOffset( double offset, bool vertical )
    {
      if( vertical )
      {
        this.SetVerticalOffset( offset );
      }
      else
      {
        this.SetHorizontalOffset( offset );
      }
    }

    private bool IsDeferredScrollingEnabled( bool fromIScrollInfoLineOrPageOperation, bool vertical )
    {
      if( !vertical )
        return false;

      if( fromIScrollInfoLineOrPageOperation )
        return false;

      ListBox listBox = this.ParentListBox;
      if( ( listBox == null ) || ( listBox.ItemScrollingBehavior != ItemScrollingBehavior.Deferred ) )
        return false;

      return PanelBase.IsDraggingThumb( this.ScrollOwner, vertical );
    }

    private void SetDeferredOffset( double offset, bool vertical )
    {
      if( vertical )
      {
        m_deferredVerticalOffset = offset;
      }
      else
      {
        m_deferredHorizontalOffset = offset;
      }
    }

    private void UpdateOffsets()
    {
      Nullable<double> horizontalOffset = m_deferredHorizontalOffset;
      Nullable<double> verticalOffset = m_deferredVerticalOffset;

      m_deferredHorizontalOffset = null;
      m_deferredVerticalOffset = null;

      if( horizontalOffset.HasValue )
      {
        this.SetHorizontalOffset( horizontalOffset.Value, animate: false );
      }

      if( verticalOffset.HasValue )
      {
        this.SetVerticalOffset( verticalOffset.Value, animate: false );
      }
    }

    private static bool IsDraggingThumb( ScrollViewer scrollViewer, bool vertical )
    {
      ScrollBar scrollBar = PanelBase.GetScrollBar( scrollViewer, vertical );
      if( scrollBar == null )
        return false;

      Thumb thumb = PanelBase.GetScrollBarThumb( scrollBar, vertical );
      if( thumb == null )
        return false;

      return thumb.IsDragging;
    }

    private static ScrollBar GetScrollBar( ScrollViewer scrollViewer, bool vertical )
    {
      if( scrollViewer == null )
        return null;

      string scrollBarPartName;

      if( vertical )
      {
        scrollBarPartName = PanelBase.VerticalScrollBarPartName;
      }
      else
      {
        scrollBarPartName = PanelBase.HorizontalScrollBarPartName;
      }

      return ( from control in PanelBase.GetDescendents( scrollViewer )
               let scrollBar = control as ScrollBar
               where ( scrollBar != null ) && ( scrollBar.Name == scrollBarPartName )
               select scrollBar ).FirstOrDefault();
    }

    private static Thumb GetScrollBarThumb( ScrollBar scrollBar, bool vertical )
    {
      if( scrollBar == null )
        return null;

      string thumbPartName;

      if( vertical )
      {
        thumbPartName = PanelBase.VerticalThumbPartName;
      }
      else
      {
        thumbPartName = PanelBase.HorizontalThumbPartName;
      }

      return ( from control in PanelBase.GetDescendents( scrollBar )
               let thumb = control as Thumb
               where ( thumb != null ) && ( thumb.Name == thumbPartName )
               select thumb ).FirstOrDefault();
    }

    private static IEnumerable<DependencyObject> GetDescendents( DependencyObject root )
    {
      if( root != null )
      {
        Queue<DependencyObject> descendents = new Queue<DependencyObject>();
        DependencyObject current = root;

        while( true )
        {
          int count = VisualTreeHelper.GetChildrenCount( current );

          for( int i = 0; i < count; i++ )
          {
            descendents.Enqueue( VisualTreeHelper.GetChild( current, i ) );
          }

          if( descendents.Count == 0 )
            break;

          current = descendents.Dequeue();

          yield return current;
        }
      }
    }

    #region Private Fields

    private Nullable<double> m_deferredHorizontalOffset;
    private Nullable<double> m_deferredVerticalOffset;

    #endregion
  }
}

#endif
